//
// Created by twetec on 25-8-16.
//

#ifndef NETWORK_PROBER_PROBE_DETECT_HANDLE_TCP_PROBE_DETECT_H
#define NETWORK_PROBER_PROBE_DETECT_HANDLE_TCP_PROBE_DETECT_H

namespace boost::json
{
struct value_from_tag;
struct value;
}

namespace network_prober::probe_detect
{
/**
 * TCP IPv4 探测结果
 */
struct TCPProbeDetectResultIPv4
{
    std::string interface;
    std::string target;
    std::uint16_t port;
    std::int64_t delay;

    friend std::ostream& operator<<(std::ostream& out, const TCPProbeDetectResultIPv4& result);
};

/**
 * TCP 探测结果 序列化
 * 注：保证 tag_invoke函数 与 TCPProbeDetectResult类 在同一个命名空间
 */
void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, TCPProbeDetectResultIPv4 const &c);

/**
 * TCP IPv4
 */
class HandleTCPProbeDetectIPv4 : public std::enable_shared_from_this<HandleTCPProbeDetectIPv4>
{
public:
    /**
     *  探测
     */
    void detect();

    /**
     * 探测到时回调
     */
    void setOnDetectedCallback(std::function<void(TCPProbeDetectResultIPv4&&)> callback);

    /**
     * @param interface 网口地址
     * @param target 目标地址
     */
    HandleTCPProbeDetectIPv4(const std::string& interface, const std::string& target);
    HandleTCPProbeDetectIPv4(const std::string& interface, const std::string& target, std::uint32_t port);
    ~HandleTCPProbeDetectIPv4();

private:
    std::string m_interface;
    std::string m_target{};
    std::string m_port;
    std::function<void(TCPProbeDetectResultIPv4&&)> m_onDetectedCallback;
};


/**
 * TCP IPv6 探测结果
 */
struct TCPProbeDetectResultIPv6
{
    std::string interface;
    std::string target;
    std::uint16_t port;
    std::int64_t delay;

    friend std::ostream& operator<<(std::ostream& out, const TCPProbeDetectResultIPv6& result);
};

/**
 * TCP 探测结果 序列化
 * 注：保证 tag_invoke函数 与 TCPProbeDetectResult类 在同一个命名空间
 */
void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, TCPProbeDetectResultIPv6 const &c);

/**
 * TCP IPv6
 */
class HandleTCPProbeDetectIPv6 : public std::enable_shared_from_this<HandleTCPProbeDetectIPv6>
{
public:
    /**
     *  探测
     */
    void detect();

    /**
     * 探测到时回调
     */
    void setOnDetectedCallback(std::function<void(TCPProbeDetectResultIPv6&&)> callback);

    /**
     * @param interface 网口地址
     * @param target 目标地址
     */
    HandleTCPProbeDetectIPv6(const std::string& interface, const std::string& target);
    HandleTCPProbeDetectIPv6(const std::string& interface, const std::string& target, std::uint32_t port);
    ~HandleTCPProbeDetectIPv6();

private:
    std::string m_interface;
    std::string m_target{};
    std::string m_port;
    std::function<void(TCPProbeDetectResultIPv6&&)> m_onDetectedCallback;
};


}



#endif //NETWORK_PROBER_PROBE_DETECT_HANDLE_TCP_PROBE_DETECT_H
